import urlJoin from "url-join";
import BugReporter from "./BugReporter.js";
import { findAllPositions } from "position-map-text-to-markdown";
import "./styles.css";

const quoteText = (text) => {
    return text.split("\n").map(line => `> ${line}`).join("\n");
};

const getContentAsync = async (contentURL) => {
    try {
        if (/^https:\/\/api\.gitcode\.com\/repos/.test(contentURL)) {
            const response = await fetch(contentURL);
            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }
            const data = await response.json();
            return decodeURIComponent(escape(atob(data.content)));
        } else {
            const response = await fetch(contentURL, { credentials: "same-origin" });
            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }
            return await response.text();
        }
    } catch (error) {
        console.error('Failed to fetch content:', error);
        throw error;
    }
};

const getResourceURL = (config, filePath, branch) => {
    if (config.markdownBaseURL) {
        return urlJoin(config.markdownBaseURL, filePath);
    }
    return urlJoin('https://gitcode.com/', config.repo, 'blob', branch, filePath);
};

const getEditURL = (config, filePath, branch) => {
    return urlJoin('https://gitcode.com/', config.repo, 'edit', branch, filePath);
};

const getContentURL = (config, filePath) => {
    if (config.private) {
        return urlJoin(
            location.origin,
            /\.gitcode\.io$/.test(config.repo) ? '' : config.repo.split('/')[1],
            'gitbook/gitbook-plugin-gitcode-issue-feedback/contents',
            filePath
        );
    } else {
        if (config.gitcodeAPIBaseURL) {
            return urlJoin(config.gitcodeAPIBaseURL, filePath);
        }
        return urlJoin('https://api.gitcode.com/repos/', config.repo, 'contents', filePath);
    }
};

const getIssueURL = (config) => {
    if (config.newIssueURL) {
        return config.newIssueURL;
    }
    return urlJoin('https://gitcode.com/', config.repo, '/issues/new');
};

const createFeedbackButton = (config) => {
    const reportElement = document.createElement('button');
    reportElement.textContent = config.label || 'Bug Report';
    reportElement.className = 'gitbook-plugin-gitcode-issue-feedback';
    reportElement.setAttribute('aria-label', 'Report an issue on GitCode');
    reportElement.setAttribute('title', 'Click to report an issue about this page');
    
    const clickEvent = ('ontouchstart' in window) ? 'touchend' : 'click';
    
    reportElement.addEventListener(clickEvent, async (event) => {
        event.preventDefault();
        
        // Add loading state
        reportElement.classList.add('loading');
        reportElement.textContent = 'Loading...';
        
        try {
            // 获取当前页面信息
            const pathname = window.location.pathname || './';
            const contentURL = getContentURL(config, pathname);
            const resourceURL = getResourceURL(config, pathname, 'master');
            const editURL = getEditURL(config, pathname, 'master');
            const chapterTitle = document.title || 'Page';
            const bug = new BugReporter(getIssueURL(config));
            const selectedText = bug.getSelectedText().trim();
            
            bug.setTitle(chapterTitle);
            
            const markdown = await getContentAsync(contentURL);
            let body = `URL: ${resourceURL}\n\n`;
            
            if (selectedText && selectedText.length > 0) {
                const matches = findAllPositions({
                    text: selectedText,
                    markdown: markdown
                });
                
                matches.forEach((match) => {
                    const editLink = `[:memo:](${editURL}#L${match.loc.start.line} "Edit")`;
                    body += quoteText(`${match.markdown}\n${editLink} <${resourceURL}#L${match.loc.start.line}>`) + '\n\n';
                });
            }
            
            bug.setBody(body);
            bug.report();
            
            // Success state
            reportElement.classList.remove('loading');
            reportElement.classList.add('success');
            reportElement.textContent = 'Issue Created!';
            
            setTimeout(() => {
                reportElement.classList.remove('success');
                reportElement.textContent = config.label || 'Bug Report';
            }, 2000);
            
        } catch (error) {
            console.error('GitCode Issue Feedback Error:', error);
            
            // Error state
            reportElement.classList.remove('loading');
            reportElement.classList.add('error');
            reportElement.textContent = 'Error!';
            
            setTimeout(() => {
                reportElement.classList.remove('error');
                reportElement.textContent = config.label || 'Bug Report';
            }, 3000);
        }
    });
    
    document.body.appendChild(reportElement);
};

// 检查是否在 GitBook 环境中
const initPlugin = (gitbook) => {
    if (!gitbook) {
        console.warn('GitCode Issue Feedback: GitBook not available, using fallback mode');
        // 在非 GitBook 环境中直接初始化
        const config = {
            repo: 'nutpi/gitbook-plugin-gitcode-issue-feedback',
            label: '报告问题',
            private: false
        };
        createFeedbackButton(config);
        return;
    }
    
    gitbook.events.bind('start', (e, pluginConfig) => {
        const config = pluginConfig['gitcode-issue-feedback'];
        
        if (!config || !config.repo) {
            console.warn('GitCode Issue Feedback: Repository configuration is missing');
            return;
        }
        
        createFeedbackButton(config);
    });
};

// 初始化插件
if (typeof window !== 'undefined') {
    if (window.require) {
        // GitBook 环境
        window.require(['gitbook'], initPlugin);
    } else {
        // 非 GitBook 环境，直接初始化
        initPlugin(null);
    }
}